﻿#pragma once
#include <define.h>
#include <data_types.hpp>

namespace lt
{
	std::vector<std::string> split_string(const std::string& str, char delim);

	std::map<std::string, std::string> parse_params(const std::string& param);

	class param
	{
		std::map<std::string, std::string> _param;
	
	public:
		
		param(const char* str)
		{
			_param = parse_params(str);
		}

		template <typename T>
		T get(const char key[]) const
		{
			return get<T>(std::string(key));
		}
	
	private:
		template <typename T>
		typename std::enable_if<std::is_same<T, const char*>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return "";
			}
			return it->second.c_str();
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, code_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return default_code;
			}
			return code_t(it->second.c_str());
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, int8_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0D;
			}
			return static_cast<int8_t>(std::atoi(it->second.c_str()));
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, uint8_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0U;
			}
			return static_cast<uint8_t>(std::atoi(it->second.c_str()));
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, int32_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0D;
			}
			return std::atoi(it->second.c_str());
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, uint32_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0U;
			}
			return static_cast<uint32_t>(std::atoi(it->second.c_str()));
		}

		template <typename T>
		typename std::enable_if<std::is_same<T, double_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return .0F;
			}
			return std::atof(it->second.c_str());
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, int64_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0LL;
			}
			return std::atoll(it->second.c_str());
		}
		template <typename T>
		typename std::enable_if<std::is_same<T, uint64_t>::value, T>::type get(const std::string& key)const
		{
			auto it = _param.find(key);
			if (it == _param.end())
			{
				return 0X0LLU;
			}
			return static_cast<uint64_t>(std::atoll(it->second.c_str()));
		}
	};

}

